<?php
declare(strict_types=1);
namespace cms\wechat\api_controller;

use cms\wechat\service\OfficialService;
use cms\wechat\service\UserService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use HyperfExt\Auth\Contracts\AuthManagerInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * Class UserController
 * @package cms\wechat\api_controller
 * @Controller(prefix="api/wechat/user")
 */
class UserController extends CommonController
{
    /**
     * @Inject()
     * @var OfficialService
     */
    protected OfficialService $officialService;

    /**
     * @Inject()
     * @var UserService
     */
    protected UserService $userService;

    /**
     * 授权操作
     * @RequestMapping(path="auth")
     */
    public function auth(): ResponseInterface
    {
        // 认证类型
        $auth_type = $this->request->input('auth_type', '');
        switch ($auth_type) {
            default:
                return $this->_authWx();
                break;
        }
    }

    /**
     * @return ResponseInterface
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Overtrue\Socialite\Exceptions\AuthorizeFailedException
     */
    protected function _authWx(): ResponseInterface
    {
        // 公众号ID
        $wx_id = (int) $this->request->input('wx_id', 0);
        // 授权作用域
        $wx_scope = (string) $this->request->input('wx_scope', 'snsapi_userinfo');

        // region 授权后回执 +++++
        $code = (string) $this->request->input('code', '');
        // 授权第三方会携带
        $app_id = (string) $this->request->input('appid', '');
        // endregion

        // 取得公众号信息
        $official = $this->officialService->getDataById($wx_id, true);
        if (!$official || $official->level != 4) {
            return $this->error('公众号不存在或不支持授权登陆');
        }
        // 初始化微信应用
        $official_application = $this->officialService->initApplication($official);
        if (!in_array($wx_scope, ['snsapi_userinfo', 'snsapi_base'])) {
            $wx_scope = 'snsapi_userinfo';
        }
        // $auth_redirect = $this->request->fullUrl();
        $auth_redirect = 'https://wx.sc-eec.cn/api/wechat/user/auth?' . $this->request->getQueryString();
        $official_application->oauth->scopes([$wx_scope])->redirect($auth_redirect);
        if ($code) {
            $oauth = $official_application->oauth->userFromCode($code);
            if ($wx_scope == 'snsapi_userinfo') {
                $user_data = $oauth->getRaw();
            } else {
                $user_data = [
                    'open_id' => $oauth->getId()
                ];
            }
            $user = $this->userService->syncDataByAuth($official, $user_data);
            // 成功重定向
            $redirect_success = $this->request->input('wx_success', '');
            if ($redirect_success) {
                $redirect_success = base64_decode(urldecode(trim($redirect_success)));
            }
            // 失败重定向
            $redirect_error = $this->request->input('wx_error', '');
            if ($redirect_error) {
                $redirect_error = base64_decode(urldecode(trim($redirect_error)));
            }
            if (!$user) {
                if ($redirect_error) {
                    return $this->response->redirect($redirect_error);
                }
                return $this->error('授权失败');
            }
            if (!$redirect_success) {
                return $this->error('授权失败');
            }
            /*
            $wx_token = cms_encode_token([
                'type' => 'wechat',
                'id' => $user->id,
                'open_id' => $user->open_id
            ]);
            */
            $wx_token = make(AuthManagerInterface::class)->guard('wechat')->login($user);
            $redirect_success = preg_replace('/[?|&]wx_id=[%+-_0-9a-zA-z]*/', '', $redirect_success);
            $redirect_success = preg_replace('/[?|&]wx_token=[%+-_0-9a-zA-z]*/', '', $redirect_success);
            $redirect_success .= strpos($redirect_success, '?') !== false ? '&' : '?';
            $redirect_success .= 'wx_id='.$official->id.'&wx_token='.$wx_token;
            return $this->response->redirect($redirect_success);
        }
        $auth_link = $official_application->oauth->redirect();
        return $this->response->redirect($auth_link);
    }

}